/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IMAGE_KNIFE_C_IMAGEKNIFE_DATA_H
#define IMAGE_KNIFE_C_IMAGEKNIFE_DATA_H

#include <cstdint>
#include <multimedia/image_framework/image/pixelmap_native.h>
#include <string>
#include <resourcemanager/ohresmgr.h>
#include <arkui/native_type.h>
#include "napi/native_api.h"
#include "constants.h"
#include "hilog/log.h"
#include "imageknife_type.h"

namespace ImageKnifeC {

// Js UIAbilityContext
struct Context {
    NativeResourceManager *resourceManager = nullptr;
};

struct OptionData {
public:
    // 类型正确返回true
    bool GetString(std::string &result) const;

    bool GetNumber(int &result) const;
    // 获取pixelMap指针， pixelmap生命周期由该类管理进行释放。
    bool GetPixelMap(OH_PixelmapNative *&result) const;
    // 移交pixelMap管理权，该类不进行pixelmap释放，操作成功返回true，并将类型设成undefined
    bool MovePixelMap(OH_PixelmapNative *&result);

    bool GetResource(Resource &result) const;

    void SetString(std::string str);

    void SetNumber(int number);
    // 设置pixelmap 指针，接管其生命周期
    void SetPixelMap(OH_PixelmapNative *pixelMap);

    void CopyFromPixelmap(OH_PixelmapNative *pixelMap);

    void SetResource(Resource resource);

    void SetValue(napi_env env, napi_value &value);

    bool IsUndefined();

    void SetUndefined();

    std::string ToString() const;

    DataType GetType() const
    {
        return type_;
    }

    OptionData() : type_(DataType::UNDEFINED) {};
    explicit OptionData(unsigned int type) : type_(DataType::UNDEFINED), availableType_(type) {};
    ~OptionData()
    {
        CleanData();
    };
private:
    union ImageSrc {
        std::string str;
        int number;
        // pixelMap has attr: createAlphaPixelmap
        OH_PixelmapNative *pixelMap;
        // Resource has attr: id
        Resource resource;
        // 由OptionData管理
        ImageSrc() : pixelMap(nullptr) {};
        ~ImageSrc() {};
    };

    unsigned int availableType_;
    DataType type_;
    ImageSrc data_;

    void CleanData();
    std::string ParseNapiString(napi_env env, napi_value vaue);
};

struct ImageSource : public OptionData {
    ImageSource() : OptionData(DataType::STRING | DataType::PIXELMAP | DataType::RESOURCE)
    {
    }

    explicit ImageSource(std::string url) : ImageSource()
    {
        SetString(url);
    }

    explicit ImageSource(const char* url) : ImageSource(std::string(url))
    {
    }

    explicit ImageSource(OH_PixelmapNative *pixelMap) : ImageSource()
    {
        SetPixelMap(pixelMap);
    }

    explicit ImageSource(Resource resource) : ImageSource()
    {
        SetResource(resource);
    }
};

} // end of namespace
#endif // IMAGE_KNIFE_C_IMAGEKNIFE_DATA_H
